home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 001 / meschach / !Meschach / c / sparseio < prev    next >
Text File  |  1994-01-13  |  8KB  |  316 lines

  1.  
  2. /**************************************************************************
  3. **
  4. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  5. **
  6. **                 Meschach Library
  7. ** 
  8. ** This Meschach Library is provided "as is" without any express 
  9. ** or implied warranty of any kind with respect to this software. 
  10. ** In particular the authors shall not be liable for any direct, 
  11. ** indirect, special, incidental or consequential damages arising 
  12. ** in any way from use of the software.
  13. ** 
  14. ** Everyone is granted permission to copy, modify and redistribute this
  15. ** Meschach Library, provided:
  16. **  1.  All copies contain this copyright notice.
  17. **  2.  All modified copies shall carry a notice stating who
  18. **      made the last modification and the date of such modification.
  19. **  3.  No charge is made for this software or works derived from it.  
  20. **      This clause shall not be construed as constraining other software
  21. **      distributed on the same medium as this software, nor is a
  22. **      distribution fee considered a charge.
  23. **
  24. ***************************************************************************/
  25.  
  26.  
  27. /*
  28.     This file has the routines for sparse matrix input/output
  29.     It works in conjunction with sparse.c, sparse.h etc
  30. */
  31.  
  32. #include        <stdio.h>
  33. #include        "sparse.h"
  34.  
  35. static char rcsid[] = "$Id: sparseio.c,v 1.4 1994/01/13 05:34:25 des Exp $";
  36.  
  37.  
  38.  
  39. /* local variables */
  40. static char line[MAXLINE];
  41.  
  42. /* sp_foutput -- output sparse matrix A to file/stream fp */
  43. void    sp_foutput(fp,A)
  44. FILE    *fp;
  45. SPMAT  *A;
  46. {
  47.     int     i, j_idx, m /* , n */;
  48.     SPROW  *rows;
  49.     row_elt *elts;
  50.  
  51.     fprintf(fp,"SparseMatrix: ");
  52.     if ( A == SMNULL )
  53.     {
  54.         fprintf(fp,"*** NULL ***\n");
  55.         error(E_NULL,"sp_foutput");    return;
  56.     }
  57.     fprintf(fp,"%d by %d\n",A->m,A->n);
  58.     m = A->m;       /* n = A->n; */
  59.     if ( ! (rows=A->row) )
  60.     {
  61.         fprintf(fp,"*** NULL rows ***\n");
  62.         error(E_NULL,"sp_foutput");    return;
  63.     }
  64.  
  65.     for ( i = 0; i < m; i++ )
  66.     {
  67.         fprintf(fp,"row %d: ",i);
  68.         if ( ! (elts=rows[i].elt) )
  69.         {
  70.             fprintf(fp,"*** NULL element list ***\n");
  71.             continue;
  72.         }
  73.         for ( j_idx = 0; j_idx < rows[i].len; j_idx++ )
  74.         {
  75.             fprintf(fp,"%d:%-20.15g ",elts[j_idx].col,
  76.                             elts[j_idx].val);
  77.             if ( j_idx % 3 == 2 && j_idx != rows[i].len-1 )
  78.                 fprintf(fp,"\n     ");
  79.         }
  80.         fprintf(fp,"\n");
  81.     }
  82.     fprintf(fp,"#\n");    /* to stop looking beyond for next entry */
  83. }
  84.  
  85. /* sp_foutput2 -- print out sparse matrix **as a dense matrix**
  86.     -- see output format used in matrix.h etc */
  87. /******************************************************************
  88. void    sp_foutput2(fp,A)
  89. FILE    *fp;
  90. SPMAT  *A;
  91. {
  92.     int     cnt, i, j, j_idx;
  93.     SPROW  *r;
  94.     row_elt *elt;
  95.  
  96.     if ( A == SMNULL )
  97.     {
  98.         fprintf(fp,"Matrix: *** NULL ***\n");
  99.         return;
  100.     }
  101.     fprintf(fp,"Matrix: %d by %d\n",A->m,A->n);
  102.     for ( i = 0; i < A->m; i++ )
  103.     {
  104.         fprintf(fp,"row %d:",i);
  105.         r = &(A->row[i]);
  106.         elt = r->elt;
  107.         cnt = j = j_idx = 0;
  108.         while ( j_idx < r->len || j < A->n )
  109.         {
  110.             if ( j_idx >= r->len )
  111.                 fprintf(fp,"%14.9g ",0.0);
  112.             else if ( j < elt[j_idx].col )
  113.                 fprintf(fp,"%14.9g ",0.0);
  114.             else
  115.                 fprintf(fp,"%14.9g ",elt[j_idx++].val);
  116.             if ( cnt++ % 4 == 3 )
  117.                 fprintf(fp,"\n");
  118.             j++;
  119.         }
  120.         fprintf(fp,"\n");
  121.     }
  122. }
  123. ******************************************************************/
  124.  
  125. /* sp_dump -- prints ALL relevant information about the sparse matrix A */
  126. void    sp_dump(fp,A)
  127. FILE    *fp;
  128. SPMAT  *A;
  129. {
  130.     int     i, j, j_idx;
  131.     SPROW  *rows;
  132.     row_elt *elts;
  133.  
  134.     fprintf(fp,"SparseMatrix dump:\n");
  135.     if ( ! A )
  136.     {       fprintf(fp,"*** NULL ***\n");   return; }
  137.     fprintf(fp,"Matrix at 0x%lx\n",(long)A);
  138.     fprintf(fp,"Dimensions: %d by %d\n",A->m,A->n);
  139.     fprintf(fp,"MaxDimensions: %d by %d\n",A->max_m,A->max_n);
  140.     fprintf(fp,"flag_col = %d, flag_diag = %d\n",A->flag_col,A->flag_diag);
  141.     fprintf(fp,"start_row @ 0x%lx:\n",(long)(A->start_row));
  142.     for ( j = 0; j < A->n; j++ )
  143.     {
  144.         fprintf(fp,"%d ",A->start_row[j]);
  145.         if ( j % 10 == 9 )
  146.             fprintf(fp,"\n");
  147.     }
  148.     fprintf(fp,"\n");
  149.     fprintf(fp,"start_idx @ 0x%lx:\n",(long)(A->start_idx));
  150.     for ( j = 0; j < A->n; j++ )
  151.     {
  152.         fprintf(fp,"%d ",A->start_idx[j]);
  153.         if ( j % 10 == 9 )
  154.             fprintf(fp,"\n");
  155.     }
  156.     fprintf(fp,"\n");
  157.     fprintf(fp,"Rows @ 0x%lx:\n",(long)(A->row));
  158.     if ( ! A->row )
  159.     {       fprintf(fp,"*** NULL row ***\n");       return; }
  160.     rows = A->row;
  161.     for ( i = 0; i < A->m; i++ )
  162.     {
  163.         fprintf(fp,"row %d: len = %d, maxlen = %d, diag idx = %d\n",
  164.             i,rows[i].len,rows[i].maxlen,rows[i].diag);
  165.         fprintf(fp,"element list @ 0x%lx\n",(long)(rows[i].elt));
  166.         if ( ! rows[i].elt )
  167.         {
  168.             fprintf(fp,"*** NULL element list ***\n");
  169.             continue;
  170.         }
  171.         elts = rows[i].elt;
  172.         for ( j_idx = 0; j_idx < rows[i].len; j_idx++, elts++ )
  173.             fprintf(fp,"Col: %d, Val: %g, nxt_row = %d, nxt_idx = %d\n",
  174.             elts->col,elts->val,elts->nxt_row,elts->nxt_idx);
  175.         fprintf(fp,"\n");
  176.     }
  177. }
  178.  
  179. #define MAXSCRATCH      100
  180.  
  181. /* sp_finput -- input sparse matrix from stream/file fp
  182.     -- uses friendly input routine if fp is a tty
  183.     -- uses format identical to output format otherwise */
  184. SPMAT  *sp_finput(fp)
  185. FILE    *fp;
  186. {
  187.     int     i, len, ret_val;
  188.     int     col, curr_col, m, n, tmp, tty;
  189.     Real  val;
  190.     SPMAT  *A;
  191.     SPROW  *rows;
  192.  
  193.     row_elt scratch[MAXSCRATCH];
  194.     /* cannot handle >= MAXSCRATCH elements in a row */
  195.  
  196.     for ( i = 0; i < MAXSCRATCH; i++ )
  197.         scratch[i].nxt_row = scratch[i].nxt_idx = -1;
  198.  
  199.     tty = isatty(fileno(fp));
  200.  
  201.     if ( tty )
  202.     {
  203.         fprintf(stderr,"SparseMatrix: ");
  204.         do {
  205.             fprintf(stderr,"input rows cols: ");
  206.             if ( ! fgets(line,MAXLINE,fp) )
  207.                 error(E_INPUT,"sp_finput");
  208.         } while ( sscanf(line,"%u %u",&m,&n) != 2 );
  209.         A = sp_get(m,n,5);
  210.         rows = A->row;
  211.  
  212.         for ( i = 0; i < m; i++ )
  213.         {
  214.             fprintf(stderr,"Row %d:\n",i);
  215.             fprintf(stderr,"Enter <col> <val> or 'e' to end row\n");
  216.             curr_col = -1;
  217.             for ( len = 0; len < MAXSCRATCH; len++ )
  218.             {
  219.             do {
  220.                 fprintf(stderr,"Entry %d: ",len);
  221.                 if ( ! fgets(line,MAXLINE,fp) )
  222.                 error(E_INPUT,"sp_finput");
  223.                 if ( *line == 'e' || *line == 'E' )
  224.                 break;
  225. #if REAL == DOUBLE
  226.             } while ( sscanf(line,"%u %lf",&col,&val) != 2 ||
  227. #elif REAL == FLOAT
  228.             } while ( sscanf(line,"%u %f",&col,&val) != 2 ||
  229. #endif
  230.                     col >= n || col <= curr_col );
  231.  
  232.             if ( *line == 'e' || *line == 'E' )
  233.                 break;
  234.  
  235.             scratch[len].col = col;
  236.             scratch[len].val = val;
  237.             curr_col = col;
  238.             }
  239.  
  240.             /* Note: len = # elements in row */
  241.             if ( len > 5 )
  242.              {
  243.             if (mem_info_is_on()) {
  244.                mem_bytes(TYPE_SPMAT,
  245.                        A->row[i].maxlen*sizeof(row_elt),
  246.                        len*sizeof(row_elt));  
  247.             }
  248.  
  249.             rows[i].elt = (row_elt *)realloc((char *)rows[i].elt,
  250.                              len*sizeof(row_elt));
  251.             rows[i].maxlen = len;
  252.             }
  253.             MEM_COPY(scratch,rows[i].elt,len*sizeof(row_elt));
  254.             rows[i].len  = len;
  255.             rows[i].diag = sprow_idx(&(rows[i]),i);
  256.         }
  257.     }
  258.     else /* not tty */
  259.     {
  260.             ret_val = 0;
  261.         skipjunk(fp);
  262.         fscanf(fp,"SparseMatrix:");
  263.         skipjunk(fp);
  264.         if ( (ret_val=fscanf(fp,"%u by %u",&m,&n)) != 2 )
  265.             error((ret_val == EOF) ? E_EOF : E_FORMAT,"sp_finput");
  266.         A = sp_get(m,n,5);
  267.  
  268.         /* initialise start_row */
  269.         for ( i = 0; i < A->n; i++ )
  270.             A->start_row[i] = -1;
  271.  
  272.         rows = A->row;
  273.         for ( i = 0; i < m; i++ )
  274.         {
  275.             /* printf("Reading row # %d\n",i); */
  276.             rows[i].diag = -1;
  277.             skipjunk(fp);
  278.             if ( (ret_val=fscanf(fp,"row %d :",&tmp)) != 1 ||
  279.              tmp != i )
  280.             error((ret_val == EOF) ? E_EOF : E_FORMAT,
  281.                   "sp_finput");
  282.             curr_col = -1;
  283.             for ( len = 0; len < MAXSCRATCH; len++ )
  284.             {
  285. #if REAL == DOUBLE
  286.             if ( (ret_val=fscanf(fp,"%u : %lf",&col,&val)) != 2 )
  287. #elif REAL == FLOAT
  288.             if ( (ret_val=fscanf(fp,"%u : %f",&col,&val)) != 2 )
  289. #endif
  290.                 break;
  291.             if ( col <= curr_col || col >= n )
  292.                 error(E_FORMAT,"sp_finput");
  293.             scratch[len].col = col;
  294.             scratch[len].val = val;
  295.             }
  296.             if ( ret_val == EOF )
  297.             error(E_EOF,"sp_finput");
  298.  
  299.             if ( len > rows[i].maxlen )
  300.             {
  301.             rows[i].elt = (row_elt *)realloc((char *)rows[i].elt,
  302.                             len*sizeof(row_elt));
  303.             rows[i].maxlen = len;
  304.             }
  305.             MEM_COPY(scratch,rows[i].elt,len*sizeof(row_elt));
  306.             rows[i].len  = len;
  307.             /* printf("Have read row # %d\n",i); */
  308.             rows[i].diag = sprow_idx(&(rows[i]),i);
  309.             /* printf("Have set diag index for row # %d\n",i); */
  310.         }
  311.     }
  312.  
  313.     return A;
  314. }
  315.  
  316.